home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 June / PCWorld_2007-06_cd.bin / v cisle / tclock / tclocklight-040702-3.exe / source / dll / wndproc.c < prev   
C/C++ Source or Header  |  2004-06-29  |  15KB  |  577 lines

  1. /*-------------------------------------------------------------
  2.   wndproc.c : subclassified window procedure of clock
  3.   (C) 1997-2003 Kazuto Sato
  4.   Please read readme.txt about the license.
  5.   
  6.   Written by Kazubon, Nanashi-san
  7. ---------------------------------------------------------------*/
  8.  
  9. #include "tcdll.h"
  10.  
  11. /* Globals */
  12. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  13. BOOL  g_bDispSecond = FALSE; // draw clock every second
  14. int   g_nBlink = 0;          // 0: no blink
  15.                              // 1: blink (normal) 2: blink (invert color)
  16.  
  17. /* Statics */
  18. static void OnTimerMain(HWND hwnd);
  19. static void OnRefreshClock(HWND hwnd);
  20. static void OnRefreshTaskbar(HWND hwnd);
  21. static void OnRefreshStartMenu(HWND hwnd);
  22. static void OnRefreshTooltip(HWND hwnd);
  23. static LRESULT OnMouseDown(HWND hwnd, UINT message,
  24.     WPARAM wParam, LPARAM lParam);
  25. static LRESULT OnMouseUp(HWND hwnd, UINT message,
  26.     WPARAM wParam, LPARAM lParam);
  27. static void OnWindowPosChanging(HWND hwnd, LPWINDOWPOS pwp);
  28. static void OnCopyData(HWND hwnd, HWND hwndFrom, const COPYDATASTRUCT* pcds);
  29. static void OnCopy(HWND hwnd, const wchar_t* fmt);
  30. static void InitDaylightTimeTransition(void);
  31. static BOOL CheckDaylightTimeTransition(const SYSTEMTIME *plt);
  32.  
  33. int   m_nBlinkSec = 0;
  34. DWORD m_nBlinkTick = 0;
  35.  
  36.  
  37. /*------------------------------------------------
  38.   subclass procedure of the clock
  39. --------------------------------------------------*/
  40. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  41. {
  42.     switch(message) // for tooltip
  43.     {
  44.         case WM_MOUSEMOVE:
  45.         case WM_LBUTTONDOWN:
  46.         case WM_RBUTTONDOWN:
  47.         case WM_MBUTTONDOWN:
  48.         case WM_LBUTTONUP:
  49.         case WM_RBUTTONUP:
  50.         case WM_MBUTTONUP:
  51.             OnTooltipMouseMsg(hwnd, message, wParam, lParam);
  52.             break;
  53.     }
  54.     
  55.     switch(message)
  56.     {
  57.         /* -------- drawing & sizing ------------- */
  58.         
  59.         case WM_PAINT:
  60.         {
  61.             PAINTSTRUCT ps;
  62.             HDC hdc;
  63.             if(g_bNoClock) break;
  64.             hdc = BeginPaint(hwnd, &ps);
  65.             OnPaint(hwnd, hdc, NULL);
  66.             EndPaint(hwnd, &ps);
  67.             return 0;
  68.         }
  69.         case WM_ERASEBKGND:
  70.             break;
  71.         
  72.         case (WM_USER+100):        // a message requesting for clock size
  73.             if(g_bNoClock) break;  // sent from parent window
  74.             return OnCalcRect(hwnd);
  75.         
  76.         case WM_WINDOWPOSCHANGING:  // size arrangement
  77.             if(g_bNoClock) break;
  78.             OnWindowPosChanging(hwnd, (LPWINDOWPOS)lParam);
  79.             break;
  80.         
  81.         case WM_SIZE:
  82.             if(g_bNoClock) break;
  83.             CreateClockDC(hwnd);    // create offscreen DC
  84.             return 0;
  85.         case WM_SYSCOLORCHANGE:
  86.             if(g_bNoClock) break;
  87.             CreateClockDC(hwnd);   // create offscreen DC
  88.             InvalidateRect(hwnd, NULL, FALSE);
  89.             return 0;
  90.         case WM_WININICHANGE:
  91.         case WM_TIMECHANGE:
  92.         case (WM_USER+101):
  93.         case WM_SETFOCUS:
  94.         case WM_KILLFOCUS:
  95.             if(g_bNoClock) break;
  96.             InvalidateRect(hwnd, NULL, FALSE);
  97.             return 0;
  98.         
  99.         /* -------- Timers ------------- */
  100.         
  101.         case WM_TIMER:
  102.             switch (wParam)
  103.             {
  104.                 case IDTIMER_MAIN:
  105.                     OnTimerMain(hwnd); return 0;
  106.             /*    case IDTIMER_SYSINFO:
  107.                     OnTimerSysInfo(hwnd); return 0; */
  108.             }
  109.             if(g_bNoClock) break;
  110.             return 0;
  111.         
  112.         /* -------- Mouse messages ------------- */
  113.         
  114.         case WM_LBUTTONDOWN:   // mouse button is down
  115.         case WM_RBUTTONDOWN:
  116.         case WM_MBUTTONDOWN:
  117.         case WM_XBUTTONDOWN:
  118.             return OnMouseDown(hwnd, message, wParam, lParam);
  119.         
  120.         case WM_LBUTTONUP:    // mouse button is up
  121.         case WM_RBUTTONUP:
  122.         case WM_MBUTTONUP:
  123.         case WM_XBUTTONUP:
  124.             return OnMouseUp(hwnd, message, wParam, lParam);
  125.         
  126.         case WM_MOUSEMOVE:
  127.             return 0;
  128.         case WM_NCRBUTTONUP:
  129.             return 0;
  130.         case WM_CONTEXTMENU:
  131.             PostMessage(g_hwndTClockMain, WM_CONTEXTMENU, wParam, lParam);
  132.             return 0;
  133.         case WM_NCHITTEST:     // not to pass to g_oldWndProc
  134.             return DefWindowProc(hwnd, message, wParam, lParam);
  135.         case WM_MOUSEACTIVATE:
  136.             return MA_ACTIVATE;
  137.         case WM_DROPFILES:     // files are dropped
  138.             PostMessage(g_hwndTClockMain, WM_DROPFILES, wParam, lParam);
  139.             return 0;
  140.         
  141.         case WM_MOUSEWHEEL:  // the mouse wheel is rotated
  142.             PostMessage(g_hwndTClockMain, WM_MOUSEWHEEL, wParam, lParam);
  143.             return 0;
  144.         
  145.         case WM_NOTIFY: // tooltip
  146.         {
  147.             LRESULT res;
  148.             if(OnTooltipNotify(hwnd, &res, (LPNMHDR)lParam)) return res;
  149.             break;
  150.         }
  151.         
  152.         /* messages sent from other program */
  153.         
  154.         case CLOCKM_EXIT:   // clean up all
  155.             EndClock(hwnd);
  156.             return 0;
  157.         case CLOCKM_REFRESHCLOCK: // refresh the clock
  158.             OnRefreshClock(hwnd);
  159.             return 0;
  160.         case CLOCKM_DELUSRSTR:    // clear user strings
  161.             InitUserStr();
  162.             return 0;
  163.         case CLOCKM_REFRESHTASKBAR: // refresh other elements than clock
  164.             OnRefreshTaskbar(hwnd);
  165.             return 0;
  166.         case CLOCKM_REFRESHSTARTMENU: // refresh Start menu
  167.             OnRefreshStartMenu(hwnd);
  168.             return 0;
  169.         case CLOCKM_REFRESHTOOLTIP: // refresh tooltip
  170.             OnRefreshTooltip(hwnd);
  171.             return 0;
  172.         case CLOCKM_BLINK: // blink the clock
  173.             g_nBlink = 2;
  174.             m_nBlinkSec = lParam;
  175.             if(lParam) m_nBlinkTick = GetTickCount();
  176.             return 0;
  177.         case CLOCKM_COPY: // copy format to clipboard
  178.             OnCopy(hwnd, NULL);
  179.             return 0;
  180.         
  181.         case WM_COPYDATA:
  182.             OnCopyData(hwnd, (HWND)wParam, (COPYDATASTRUCT*)lParam);
  183.             return 0;
  184.         
  185.         /* WM_DESTROY is sent only when Win95+IE4/98/Me is shut down */
  186.         
  187.         case WM_DESTROY:
  188.             OnDestroy(hwnd); // main2.c
  189.             break;
  190.     }
  191.     
  192.     return CallWindowProc(g_oldWndProc, hwnd, message, wParam, lParam);
  193. }
  194.  
  195. /*------------------------------------------------
  196.   WM_TIMER message, wParam = IDTIMER_MAIN
  197. --------------------------------------------------*/
  198. void OnTimerMain(HWND hwnd)
  199. {
  200.     static SYSTEMTIME LastTime = { 0, 0, 0, 0, 0, 0, 0, 0 };
  201.     static BOOL bTimerAdjusting = FALSE;
  202.     SYSTEMTIME t;
  203.     HDC hdc;
  204.     BOOL bRedraw;
  205.     
  206.     GetLocalTime(&t);
  207.     
  208.     // adjusting milliseconds gap
  209.     if((t.wMilliseconds > 200 ||
  210.         ((g_winver | WINNT) && t.wMilliseconds > 50)))
  211.     {
  212.         KillTimer(hwnd, IDTIMER_MAIN);
  213.         SetTimer(hwnd, IDTIMER_MAIN, 1001 - t.wMilliseconds, NULL);
  214.         bTimerAdjusting = TRUE;
  215.     }
  216.     else if(bTimerAdjusting)
  217.     {
  218.         KillTimer(hwnd, IDTIMER_MAIN);
  219.         bTimerAdjusting = FALSE;
  220.         SetTimer(hwnd, IDTIMER_MAIN, 1000, NULL);
  221.     }
  222.     
  223.     bRedraw = FALSE;
  224.     
  225.     if(g_nBlink && m_nBlinkSec)
  226.     {
  227.         if(GetTickCount() - m_nBlinkTick > (DWORD)m_nBlinkSec*1000)
  228.         {
  229.             g_nBlink = 0; bRedraw = TRUE;
  230.         }
  231.     }
  232.     
  233.     if(g_nBlink > 0) bRedraw = TRUE;
  234.     else if(g_bDispSecond) bRedraw = TRUE;
  235.     else if(LastTime.wHour != (int)t.wHour 
  236.         || LastTime.wMinute != (int)t.wMinute) bRedraw = TRUE;
  237.     
  238.     
  239.     if(g_bNoClock) bRedraw = FALSE;
  240.     
  241.     // date changed
  242.     if(LastTime.wDay != t.wDay || LastTime.wMonth != t.wMonth ||
  243.         LastTime.wYear != t.wYear)
  244.     {
  245.         InitFormatTime(); // formattime.c
  246.         if(!(g_winver&WINNT))
  247.             InitDaylightTimeTransition();
  248.     }
  249.     
  250.     hdc = NULL;
  251.     if(bRedraw) hdc = GetDC(hwnd);
  252.     
  253.     if(hdc)
  254.     {
  255.         OnPaint(hwnd, hdc, &t); // draw.c: draw the clock
  256.         ReleaseDC(hwnd, hdc);
  257.     }
  258.     
  259.     if(g_nBlink)
  260.     {
  261.         if(g_nBlink % 2) g_nBlink++; else g_nBlink--;
  262.     }
  263.     
  264.     // check daylight/standard time transition
  265.     if(!(g_winver&WINNT) && LastTime.wHour != t.wHour)
  266.     {
  267.         if(CheckDaylightTimeTransition(&t))
  268.             PostMessage(hwnd, WM_USER+102, 0, 0);
  269.     }
  270.     
  271.     memcpy(&LastTime, &t, sizeof(t));
  272.     
  273.     CheckCursorOnStartButton(); // startbtn.c
  274.     
  275.     CheckStartMenu(); // startmenu.c
  276.     
  277.     OnTimerTooltip(hwnd); // tooltip.c
  278. }
  279.  
  280. /*------------------------------------------------
  281.   CLOCKM_REFRESHCLOCK message
  282. --------------------------------------------------*/
  283. void OnRefreshClock(HWND hwnd)
  284. {
  285.     LoadSetting(hwnd); // reload settings
  286.     
  287.     CreateClockDC(hwnd); // draw.c
  288.     
  289.     InitTrayNotify(hwnd); // traynotify.c
  290.     
  291.     // InitUserStr(); // userstr.c
  292.     
  293.     PostMessage(GetParent(GetParent(hwnd)), WM_SIZE,
  294.         SIZE_RESTORED, 0);
  295.     PostMessage(GetParent(hwnd), WM_SIZE,
  296.         SIZE_RESTORED, 0);
  297.     
  298.     InvalidateRect(hwnd, NULL, FALSE);
  299.     InvalidateRect(GetParent(hwnd), NULL, TRUE);
  300. }
  301.  
  302. /*------------------------------------------------
  303.   CLOCKM_REFRESHTASKBAR message
  304. --------------------------------------------------*/
  305. void OnRefreshTaskbar(HWND hwnd)
  306. {
  307.     g_bVisualStyle = IsXPVisualStyle();
  308.     
  309.     ResetStartButton(hwnd); // startbtn.c
  310.     InitTaskbar(hwnd);      // taskbar.c
  311.     InitTaskSwitch(hwnd);   // taskswitch.c
  312.     
  313.     RefreshTaskbar(hwnd); // taskbar.c
  314. }
  315.  
  316. /*------------------------------------------------
  317.   CLOCKM_REFRESHSTARTMENU message
  318. --------------------------------------------------*/
  319. void OnRefreshStartMenu(HWND hwnd)
  320. {
  321.     ResetStartMenu(hwnd);
  322.     
  323.     if(!g_bIE4) InitTaskbar(hwnd);
  324. }
  325.  
  326. /*------------------------------------------------
  327.   CLOCKM_REFRESHTOOLTIP message
  328. --------------------------------------------------*/
  329. void OnRefreshTooltip(HWND hwnd)
  330. {
  331.     EndTooltip(hwnd);
  332.     InitTooltip(hwnd);
  333. }
  334.  
  335. /*------------------------------------------------
  336.   WM_xxBUTTONDOWN message
  337. --------------------------------------------------*/
  338. LRESULT OnMouseDown(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  339. {
  340.     if(message == WM_LBUTTONDOWN)
  341.         SetFocus(hwnd);
  342.     
  343.     if(g_sdisp2[0] || g_scat2[0])
  344.     {
  345.         g_sdisp2[0] = g_scat2[0] = 0;
  346.         ClearClockDC();
  347.         InvalidateRect(hwnd, NULL, FALSE);
  348.     }
  349.     
  350.     if(g_nBlink)
  351.     {
  352.         g_nBlink = 0; InvalidateRect(hwnd, NULL, FALSE);
  353.     }
  354.     
  355.     if(StartMenuFromClock(message, wParam, lParam))  // startbtn.c
  356.         return 0;
  357.     
  358.     PostMessage(g_hwndTClockMain, message, wParam, lParam);
  359.     return 0;
  360. }
  361.  
  362. /*------------------------------------------------
  363.   WM_xxBUTTONUP message
  364. --------------------------------------------------*/
  365. LRESULT OnMouseUp(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  366. {
  367.     PostMessage(g_hwndTClockMain, message, wParam, lParam);
  368.     return 0;
  369. }
  370.  
  371. /*------------------------------------------------
  372.   WM_WINDOWPOSCHANGING message
  373. --------------------------------------------------*/
  374. void OnWindowPosChanging(HWND hwnd, LPWINDOWPOS pwp)
  375. {
  376.     DWORD dw;
  377.     int h, w;
  378.     
  379.     if(g_bNoClock || g_bFitClock) return;
  380.     
  381.     if(!IsWindowVisible(hwnd) || (pwp->flags & SWP_NOSIZE))
  382.         return;
  383.     
  384.     dw = OnCalcRect(hwnd);
  385.     w = LOWORD(dw); h = HIWORD(dw);
  386.     if(pwp->cx > w) pwp->cx = w;
  387.     if(pwp->cy > h) pwp->cy = h;
  388. }
  389.  
  390. /*------------------------------------------------
  391.   WM_COPYDATA message
  392. --------------------------------------------------*/
  393. void OnCopyData(HWND hwnd, HWND hwndFrom, const COPYDATASTRUCT* pcds)
  394. {
  395.     const wchar_t *p = (const wchar_t *)pcds->lpData;
  396.     wchar_t* dst;
  397.     BOOL bRefresh = FALSE, bResize = FALSE;
  398.     
  399.     switch(pcds->dwData)
  400.     {
  401.         case COPYDATA_USTR0:
  402.         case COPYDATA_USTR1:
  403.         case COPYDATA_USTR2:
  404.         case COPYDATA_USTR3:
  405.         case COPYDATA_USTR4:
  406.         case COPYDATA_USTR5:
  407.         case COPYDATA_USTR6:
  408.         case COPYDATA_USTR7:
  409.         case COPYDATA_USTR8:
  410.         case COPYDATA_USTR9:
  411.         {
  412.             if(wcslen(p) < BUFSIZE_USTR)
  413.             {
  414.                 BOOL bEmptyLast;
  415.                 
  416.                 dst = g_userstr[pcds->dwData - COPYDATA_USTR0];
  417.                 bEmptyLast = !dst[0];
  418.                 wcscpy(dst, p);
  419.                 
  420.                 if(*p && bEmptyLast) bResize = TRUE;
  421.                 else if(*p == 0 && !bEmptyLast) bResize = TRUE;
  422.                 bRefresh = TRUE;
  423.             }
  424.             break;
  425.         }
  426.         case COPYDATA_DISP1:
  427.         case COPYDATA_DISP2:
  428.         case COPYDATA_CAT1:
  429.         case COPYDATA_CAT2:
  430.             if(wcslen(p) < BUFSIZE_DISP)
  431.             {
  432.                 BOOL bEmptyLast;
  433.                 
  434.                 if(pcds->dwData == COPYDATA_DISP1) dst = g_sdisp1;
  435.                 else if(pcds->dwData == COPYDATA_DISP2) dst = g_sdisp2;
  436.                 else if(pcds->dwData == COPYDATA_CAT1) dst = g_scat1;
  437.                 else dst = g_scat2;
  438.                 
  439.                 bEmptyLast = !dst[0];
  440.                 wcscpy(dst, p);
  441.                 
  442.                 if(*p && bEmptyLast) bResize = TRUE;
  443.                 else if(*p == 0 && !bEmptyLast) bResize = TRUE;
  444.                 bRefresh = TRUE;
  445.             }
  446.             break;
  447.         case COPYDATA_COPY:
  448.             OnCopy(hwnd, p);
  449.             break;
  450.     }
  451.     
  452.     if(bResize) ClearClockDC();
  453.     if(bRefresh && !g_bDispSecond) InvalidateRect(hwnd, NULL, FALSE);
  454. }
  455.  
  456. /*------------------------------------------------
  457.   copy date/time text to clipboard
  458. --------------------------------------------------*/
  459. void OnCopy(HWND hwnd, const wchar_t* pfmt)
  460. {
  461.     wchar_t format[BUFSIZE_FORMAT];
  462.     wchar_t ws[BUFSIZE_FORMAT];
  463.     HGLOBAL hg;
  464.     
  465.     if(pfmt)
  466.     {
  467.         if(wcslen(pfmt) < BUFSIZE_FORMAT - 5)
  468.         {
  469.             wcscpy(format, L"<%");
  470.             wcscat(format, pfmt);
  471.             wcscat(format, L"%>");
  472.             pfmt = format;
  473.         }
  474.         else return;
  475.     }
  476.     
  477.     MakeFormat(ws, NULL, pfmt, BUFSIZE_FORMAT);
  478.     
  479.     if(!OpenClipboard(hwnd)) return;
  480.     EmptyClipboard();
  481.     
  482.     if(g_winver&WINNT)
  483.     {
  484.         wchar_t *p;
  485.         
  486.         hg = GlobalAlloc(GMEM_DDESHARE, (wcslen(ws) + 1) * sizeof(wchar_t));
  487.         p = (wchar_t*)GlobalLock(hg);
  488.         wcscpy(p, ws);
  489.         GlobalUnlock(hg);
  490.         SetClipboardData(CF_UNICODETEXT, hg);
  491.     }
  492.     else
  493.     {
  494.         char s[BUFSIZE_FORMAT], *p;
  495.         
  496.         WideCharToMultiByte(CP_ACP, 0, ws, -1, s, BUFSIZE_FORMAT-1,
  497.             NULL, NULL);
  498.         
  499.         hg = GlobalAlloc(GMEM_DDESHARE, strlen(s) + 1);
  500.         p = (char*)GlobalLock(hg);
  501.         strcpy(p, s);
  502.         GlobalUnlock(hg);
  503.         SetClipboardData(CF_TEXT, hg);
  504.     }
  505.     
  506.     CloseClipboard();
  507. }
  508.  
  509. static int m_iHourTransition = -1, m_iMinuteTransition = -1;
  510.  
  511. /*------------------------------------------------
  512.   initialize time-zone information
  513. --------------------------------------------------*/
  514. void InitDaylightTimeTransition(void)
  515. {
  516.     SYSTEMTIME lt, *plt;
  517.     TIME_ZONE_INFORMATION tzi;
  518.     DWORD dw;
  519.     BOOL b;
  520.     
  521.     m_iHourTransition = m_iMinuteTransition = -1;
  522.     
  523.     GetLocalTime(<);
  524.     
  525.     b = FALSE;
  526.     memset(&tzi, 0, sizeof(tzi));
  527.     dw = GetTimeZoneInformation(&tzi);
  528.     if(dw == TIME_ZONE_ID_STANDARD
  529.       && tzi.DaylightDate.wMonth == lt.wMonth
  530.       && tzi.DaylightDate.wDayOfWeek == lt.wDayOfWeek)
  531.     {
  532.         b = TRUE; plt = &(tzi.DaylightDate);
  533.     }
  534.     if(dw == TIME_ZONE_ID_DAYLIGHT
  535.       && tzi.StandardDate.wMonth == lt.wMonth
  536.       && tzi.StandardDate.wDayOfWeek == lt.wDayOfWeek)
  537.     {
  538.         b = TRUE; plt = &(tzi.StandardDate);
  539.     }
  540.     
  541.     if(b && plt->wDay < 5)
  542.     {
  543.         if(((lt.wDay - 1) / 7 + 1) == plt->wDay)
  544.         {
  545.             m_iHourTransition = plt->wHour;
  546.             m_iMinuteTransition = plt->wMinute;
  547.         }
  548.     }
  549.     else if(b && plt->wDay == 5)
  550.     {
  551.         FILETIME ft;
  552.         SystemTimeToFileTime(<, &ft);
  553.         *(DWORDLONG*)&ft += 6048000000000i64;
  554.         FileTimeToSystemTime(&ft, <);
  555.         if(lt.wDay < 8)
  556.         {
  557.             m_iHourTransition = plt->wHour;
  558.             m_iMinuteTransition = plt->wMinute;
  559.         }
  560.     }
  561. }
  562.  
  563. /*------------------------------------------------
  564.   check standard/daylight saving time transition
  565. --------------------------------------------------*/
  566. BOOL CheckDaylightTimeTransition(const SYSTEMTIME *plt)
  567. {
  568.     if((int)plt->wHour == m_iHourTransition &&
  569.        (int)plt->wMinute >= m_iMinuteTransition)
  570.     {
  571.         m_iHourTransition = m_iMinuteTransition = -1;
  572.         return TRUE;
  573.     }
  574.     else return FALSE;
  575. }
  576.  
  577.